#pragma once

#include <string>
#include <cstring>
#include <sys/epoll.h>
#include "Log.hpp"
#include "Error.hpp"
#include "sock_tcp.hpp"
#include "sock_tcp.hpp"

class Epoller
{
private:
    const static int gsize = 128;
    const static int defaultfd = -1;

public:
    Epoller()
        : _epfd(defaultfd)
    {
    }
    ~Epoller()
    {
        if (_epfd != defaultfd)
        {
            close(_epfd);
        }
    }

    void create()
    {
        _epfd = epoll_create(gsize);
        if (_epfd == defaultfd)
        {
            logMessage(Error, "epoll_create error");
            exit(EPOLL_CREATE_ERROR);
        }
        logMessage(Debug, "epoll_create success");
    }

    bool addEvent(int fd, uint32_t events)
    {
        struct epoll_event ev;
        memset(&ev, 0, sizeof(ev));
        ev.data.fd = fd;
        ev.events = events;

        int ret = epoll_ctl(_epfd, EPOLL_CTL_ADD, fd, &ev);
        if (ret == -1)
        {
            logMessage(Error, "epoll_ctl add error");
            return false;
        }
        logMessage(Debug, "epoll_ctl add success");

        return true;
    }

    bool delEvent(int fd)
    {
        int ret = epoll_ctl(_epfd, EPOLL_CTL_DEL, fd, nullptr);
        if (ret == -1)
        {
            logMessage(Error, "epoll_ctl del error");
            return false;
        }
        logMessage(Debug, "epoll_ctl del success");

        return true;
    }

    int wait(struct epoll_event *events, int maxevents, int timeout)
    {
        int ret = epoll_wait(_epfd, events, maxevents, timeout);
        if (ret == -1)
        {
            logMessage(Error, "epoll_wait error");
            return -1;
        }
        logMessage(Debug, "epoll_wait success");

        return ret;
    }

    int Fd()
    {
        return _epfd;
    }

private:
    int _epfd;
};